package com.nbufe.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nbufe.domain.ResponseResult;
import com.nbufe.domain.dto.data.YearMonthRangeDto;
import com.nbufe.domain.entity.*;
import com.nbufe.domain.entity.Process;
import com.nbufe.domain.vo.PercentVo;
import com.nbufe.domain.vo.data.*;
import com.nbufe.enums.StageEnum;
import com.nbufe.mapper.*;
import com.nbufe.service.CarbonTargetService;
import com.nbufe.service.DataService;
import com.nbufe.service.EmissionOriginService;
import com.nbufe.service.FossilFuelService;
import com.nbufe.utils.AnalysisUtil;
import com.nbufe.utils.FormatUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.nbufe.constant.Constant.*;

/**
 * @author LZH
 * @date 2023/4/7
 */
@Service
public class DataServiceImpl implements DataService {

    @Resource
    private CarbonTargetService carbonTargetService;

    @Resource
    private FossilFuelMapper fossilFuelMapper;

    @Resource
    private IndustoryProduceMapper industoryProduceMapper;

    @Resource
    private ElectricHeatMapper electricHeatMapper;

    @Resource
    private FixCarbonMapper fixCarbonMapper;

    @Resource
    private EmissionOriginMapper emissionOriginMapper;

    @Resource
    private ProcessMapper processMapper;

    @Override
    public Map<String, Object> listYearVaryMaterialOneTo12CO2(Integer year, Integer stage) {
        if (1 == stage) {
            //所有材料总CO2
            BigDecimal total = new BigDecimal(0);
            //获取所有不同的材料id
            List<Long> materialIdList = queryTargetStageMaterialIds(1);
            Map<Long, List<EmissionOrigin>> map = queryTargetStageEmissionOrigins(1);

            List<Year1To12MonthMaterialVo> materialVoList = fossilFuelMapper.queryYearEmissionOrigin1To12CO2(year);
            return getEmissionInfo(total, materialIdList, materialVoList, map);
        } else if (2 == stage) {
            //所有材料总CO2
            BigDecimal total = new BigDecimal(0);
            //获取所有不同的材料id
            List<Long> materialIdList = queryTargetStageMaterialIds(2);
            Map<Long, List<EmissionOrigin>> map = queryTargetStageEmissionOrigins(2);

            List<Year1To12MonthMaterialVo> materialVoList = industoryProduceMapper.queryYearEmissionOrigin1To12CO2(year);
            return getEmissionInfo(total, materialIdList, materialVoList, map);
        } else if (3 == stage) {
            //所有材料总CO2
            BigDecimal total = new BigDecimal(0);
            //获取所有不同的材料id
            List<Long> materialIdList = queryTargetStageMaterialIds(3);
            Map<Long, List<EmissionOrigin>> map = queryTargetStageEmissionOrigins(3);

            List<Year1To12MonthMaterialVo> materialVoList = electricHeatMapper.queryYearEmissionOrigin1To12CO2(year);
            return getEmissionInfo(total, materialIdList, materialVoList, map);
        } else if (4 == stage) {
            //所有材料总CO2
            BigDecimal total = new BigDecimal(0);
            //获取所有不同的材料id
            List<Long> materialIdList = queryTargetStageMaterialIds(4);
            Map<Long, List<EmissionOrigin>> map = queryTargetStageEmissionOrigins(4);

            List<Year1To12MonthMaterialVo> materialVoList = fixCarbonMapper.queryYearEmissionOrigin1To12CO2(year);
            return getEmissionInfo(total, materialIdList, materialVoList, map);
        }
        return new HashMap<>();
    }

    private static Map<String, Object> getEmissionInfo(BigDecimal total, List<Long> materialIdList, List<Year1To12MonthMaterialVo> materialVoList, Map<Long, List<EmissionOrigin>> map) {
        Map<Long, List<Year1To12MonthMaterialVo>> materialIdMap = materialVoList.stream()
                .collect(Collectors.groupingBy(Year1To12MonthMaterialVo::getId));

        for (Long materialId : materialIdList) {
            materialIdMap.computeIfAbsent(materialId, k -> new ArrayList<>());
        }

        List<List<Year1To12MonthMaterialVo>> varyMaterialList = new ArrayList<>();
        for (Map.Entry<Long, List<Year1To12MonthMaterialVo>> entry : materialIdMap.entrySet()) {
            Long id = entry.getKey();
            List<Year1To12MonthMaterialVo> voList = entry.getValue();
            voList = voList.stream().sorted((Comparator.comparing(Year1To12MonthMaterialVo::getMonth))).collect(Collectors.toList());
            Map<Integer, List<Year1To12MonthMaterialVo>> monthMap = voList.stream().collect(Collectors.groupingBy(Year1To12MonthMaterialVo::getMonth));
            List<Year1To12MonthMaterialVo> materialVos = new ArrayList<>();
            for (int i = 1; i <= 12; i++) {
                if (monthMap.get(i) == null) {
                    Year1To12MonthMaterialVo vo = new Year1To12MonthMaterialVo();
                    vo.setId(id);
                    vo.setMonth(i);
                    vo.setCarbonEmission(0.0);
                    vo.setName(map.get(id).get(0).getName());
                    materialVos.add(vo);
                } else {
                    materialVos.add(monthMap.get(i).get(0));
                    total = total.add(BigDecimal.valueOf(monthMap.get(i).get(0).getCarbonEmission()));
                }
            }
            varyMaterialList.add(materialVos);
        }

        Map<String, Object> res = new HashMap<>();
        res.put("total", total.setScale(2, RoundingMode.UP).doubleValue());
        res.put("list", varyMaterialList);
        return res;
    }

    @Override
    public List<Long> queryTargetStageMaterialIds(int stage) {
        List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);
        return emissionOriginList.stream()
                .filter(emissionOrigin -> {
                    List<Integer> stageList = JSON.parseArray(emissionOrigin.getProduceStage(), Integer.class);
                    return stageList.contains(stage);
                })
                .map(EmissionOrigin::getId)
                .collect(Collectors.toList());
    }

    public Map<Long, List<EmissionOrigin>> queryTargetStageEmissionOrigins(int stage) {
        List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);
        Map<Long, List<EmissionOrigin>> map = emissionOriginList.stream()
                .filter(emissionOrigin -> {
                    List<Integer> stageList = JSON.parseArray(emissionOrigin.getProduceStage(), Integer.class);
                    return stageList.contains(stage);
                })
                .collect(Collectors.groupingBy(EmissionOrigin::getId));
        return map;
    }

    @Override
    public List<EmissionOrigin> queryTargetStageEmissionOrigin(int stage) {
        List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);
        return emissionOriginList.stream()
                .filter(emissionOrigin -> {
                    List<Integer> stageList = JSON.parseArray(emissionOrigin.getProduceStage(), Integer.class);
                    return stageList.contains(stage);
                })
                .collect(Collectors.toList());
    }

    @Override
    public Map<String, Double> queryTotalStageYearCO2(Integer year) {
        Map<String, Double> map = new HashMap<>();

        LambdaQueryWrapper<FossilFuel> fossilFuelLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fossilFuelLambdaQueryWrapper.eq(FossilFuel::getYear, year);
        List<FossilFuel> fossilFuelList = fossilFuelMapper.selectList(fossilFuelLambdaQueryWrapper);
        double fossilFuel = fossilFuelList.stream()
                .mapToDouble(FossilFuel::getCarbonEmission)
                .sum();
        map.put(FUEL_COMBUSTION, fossilFuel);

        LambdaQueryWrapper<IndustoryProduce> industoryProduceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        industoryProduceLambdaQueryWrapper.eq(IndustoryProduce::getYear, year);
        List<IndustoryProduce> industoryProduceList = industoryProduceMapper.selectList(industoryProduceLambdaQueryWrapper);
        double industryProduce = industoryProduceList.stream()
                .mapToDouble(IndustoryProduce::getCarbonEmission)
                .sum();
        map.put(INDUSTRY_PRODUCE, industryProduce);

        LambdaQueryWrapper<ElectricHeat> electricHeatLambdaQueryWrapper = new LambdaQueryWrapper<>();
        electricHeatLambdaQueryWrapper.eq(ElectricHeat::getYear, year);
        List<ElectricHeat> electricHeatList = electricHeatMapper.selectList(electricHeatLambdaQueryWrapper);
        double electricHeat = electricHeatList.stream()
                .mapToDouble(ElectricHeat::getCarbonEmission)
                .sum();
        map.put(ELECTRIC_HEAT, electricHeat);

        LambdaQueryWrapper<FixCarbon> fixCarbonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fixCarbonLambdaQueryWrapper.eq(FixCarbon::getYear, year);
        List<FixCarbon> fixCarbonList = fixCarbonMapper.selectList(fixCarbonLambdaQueryWrapper);
        double fixCarbon = fixCarbonList.stream()
                .mapToDouble(FixCarbon::getCarbonEmission)
                .sum();
        map.put(CARBON_SEQUESTRATION_PRODUCT, fixCarbon);
        return map;
    }

    @Override
    public List<List<MonthRangeVo>> queryStageMonthRangeCO2(YearMonthRangeDto dto) {
        String begin = dto.getBegin();
        String end = dto.getEnd();
        Integer beginYear = Integer.valueOf(begin.split("-")[0]);
        int endYear = Integer.parseInt(end.split("-")[0]);

        List<MonthRangeVo> monthRangeVoList1 = new ArrayList<>();
        List<MonthRangeVo> monthRangeVoList2 = new ArrayList<>();
        List<MonthRangeVo> monthRangeVoList3 = new ArrayList<>();
        List<MonthRangeVo> monthRangeVoList4 = new ArrayList<>();

        List<MonthRangeVo> fossiFuelMonthRangeVos = fossilFuelMapper.queryStageMonthRangeCO2(dto);
        Map<Integer, List<MonthRangeVo>> yearMap1 = fossiFuelMonthRangeVos.stream().collect(Collectors.groupingBy(MonthRangeVo::getYear));

        List<MonthRangeVo> industryProduceMonthRangeVos = industoryProduceMapper.queryStageMonthRangeCO2(dto);
        Map<Integer, List<MonthRangeVo>> yearMap2 = industryProduceMonthRangeVos.stream().collect(Collectors.groupingBy(MonthRangeVo::getYear));

        List<MonthRangeVo> electricHeatMonthRangeVos = electricHeatMapper.queryStageMonthRangeCO2(dto);
        Map<Integer, List<MonthRangeVo>> yearMap3 = electricHeatMonthRangeVos.stream().collect(Collectors.groupingBy(MonthRangeVo::getYear));

        List<MonthRangeVo> fixCarbonMonthRangeVos = fixCarbonMapper.queryStageMonthRangeCO2(dto);
        Map<Integer, List<MonthRangeVo>> yearMap4 = fixCarbonMonthRangeVos.stream().collect(Collectors.groupingBy(MonthRangeVo::getYear));
        while (beginYear <= endYear) {
            if (yearMap1.get(beginYear) == null) {
                monthRangeVoList1.add(new MonthRangeVo(beginYear, 0.0));
            } else {
                monthRangeVoList1.add(yearMap1.get(beginYear).get(0));
            }

            if (yearMap2.get(beginYear) == null) {
                monthRangeVoList2.add(new MonthRangeVo(beginYear, 0.0));
            } else {
                monthRangeVoList2.add(yearMap2.get(beginYear).get(0));
            }

            if (yearMap3.get(beginYear) == null) {
                monthRangeVoList3.add(new MonthRangeVo(beginYear, 0.0));
            } else {
                monthRangeVoList3.add(yearMap3.get(beginYear).get(0));
            }

            if (yearMap4.get(beginYear) == null) {
                monthRangeVoList4.add(new MonthRangeVo(beginYear, 0.0));
            } else {
                monthRangeVoList4.add(yearMap4.get(beginYear).get(0));
            }
            beginYear++;
        }
        List<List<MonthRangeVo>> result = new ArrayList<>();
        result.add(monthRangeVoList1);
        result.add(monthRangeVoList2);
        result.add(monthRangeVoList3);
        result.add(monthRangeVoList4);
        return result;
    }

    @Override
    public List<YearRangeVo> queryYearRangeTotalCO2(YearMonthRangeDto dto) {
        List<List<MonthRangeVo>> monthRangeCO2 = queryStageMonthRangeCO2(dto);
        if (CollectionUtils.isEmpty(monthRangeCO2)) {
            return new ArrayList<>();
        }
        int yearNum = monthRangeCO2.get(0).size();

        List<YearRangeVo> yearRangeVoList = new ArrayList<>();
        for (int i = 0; i < yearNum; i++) {
            BigDecimal total = new BigDecimal(0);
            int year = -1;
            for (int j = 0; j < monthRangeCO2.size(); j++) {
                year = monthRangeCO2.get(j).get(i).getYear();
                if (j == 3) {
                    total = total.subtract(BigDecimal.valueOf(monthRangeCO2.get(j).get(i).getCarbonEmission()));
                } else {
                    total = total.add(BigDecimal.valueOf(monthRangeCO2.get(j).get(i).getCarbonEmission()));
                }
            }
            yearRangeVoList.add(new YearRangeVo(year, total.setScale(2, RoundingMode.UP).doubleValue()));
        }
        return yearRangeVoList;
    }

    @Override
    public ResponseResult queryProcessByEmissionOrigin(Long id) {
        List<Process> processes = processMapper.selectList(null);
        List<Process> processeList = new ArrayList<>();
        for (Process process : processes) {
            List<Long> ids = JSON.parseArray(process.getEmissionOrigin(), Long.class);
            if (ids.contains(id)) {
                processeList.add(process);
            }
        }
        return ResponseResult.okResult(processeList);
    }

    @Override
    public ResponseResult queryAllProcessEmissionOrigin(Integer year) {
        Map<String, Double> stageYearMap = queryTotalStageYearCO2(year);
        double totalYearCarbonEmission = 0.0;
        totalYearCarbonEmission += stageYearMap.get(FUEL_COMBUSTION);
        totalYearCarbonEmission += stageYearMap.get(INDUSTRY_PRODUCE);
        totalYearCarbonEmission += stageYearMap.get(ELECTRIC_HEAT);
        totalYearCarbonEmission += stageYearMap.get(CARBON_SEQUESTRATION_PRODUCT);

        List<IndustoryProduce> industoryProduceList = industoryProduceMapper.queryAllProcessEmissionOrigin(year);
        industoryProduceList = CollectionUtils.isEmpty(industoryProduceList) ? new ArrayList<>() : industoryProduceList;
        Map<Long, List<IndustoryProduce>> processMap = industoryProduceList.stream().filter(e -> e.getProcessId() != null).collect(Collectors.groupingBy(IndustoryProduce::getProcessId));

        List<ElectricHeat> electricHeatList = electricHeatMapper.queryAllProcessEmissionOrigin(year);
        electricHeatList = CollectionUtils.isEmpty(electricHeatList) ? new ArrayList<>() : electricHeatList;
        Map<Long, List<ElectricHeat>> processMap1 = electricHeatList.stream().filter(e -> e.getProcessId() != null).collect(Collectors.groupingBy(ElectricHeat::getProcessId));

        List<FossilFuel> fossilFuelList = fossilFuelMapper.queryAllProcessEmissionOrigin(year);
        fossilFuelList = CollectionUtils.isEmpty(fossilFuelList) ? new ArrayList<>() : fossilFuelList;
        Map<Long, List<FossilFuel>> processMap2 = fossilFuelList.stream().filter(e -> e.getProcessId() != null).collect(Collectors.groupingBy(FossilFuel::getProcessId));

        List<FixCarbon> fixCarbonList = fixCarbonMapper.queryAllProcessEmissionOrigin(year);
        fixCarbonList = CollectionUtils.isEmpty(fixCarbonList) ? new ArrayList<>() : fixCarbonList;
        Map<Long, List<FixCarbon>> processMap3 = fixCarbonList.stream().filter(e -> e.getProcessId() != null).collect(Collectors.groupingBy(FixCarbon::getProcessId));

        List<Process> processList = processMapper.selectList(null);
        List<ProcessEmissionVo> processEmissionVoList = new ArrayList<>();
        for (Process process : processList) {
            Long processId = process.getId();
            ProcessEmissionVo processEmissionVo = new ProcessEmissionVo();
            processEmissionVo.setProcessId(processId);
            processEmissionVo.setProcessName(process.getName());

            List<IndustoryProduce> list = processMap.get(processId);
            List<ElectricHeat> list1 = processMap1.get(processId);
            List<FossilFuel> list2 = processMap2.get(processId);
            List<FixCarbon> list3 = processMap3.get(processId);

            double carbonEmission = 0.0;
            if (!CollectionUtils.isEmpty(list)) {
                carbonEmission += list.stream().mapToDouble(IndustoryProduce::getCarbonEmission).sum();
            }
            if (!CollectionUtils.isEmpty(list1)) {
                carbonEmission += list1.stream().mapToDouble(ElectricHeat::getCarbonEmission).sum();
            }
            if (!CollectionUtils.isEmpty(list2)) {
                carbonEmission += list2.stream().mapToDouble(FossilFuel::getCarbonEmission).sum();
            }
            if (!CollectionUtils.isEmpty(list3)) {
                carbonEmission += list3.stream().mapToDouble(FixCarbon::getCarbonEmission).sum();
            }
            processEmissionVo.setCarbonEmission(FormatUtil.saveTwoDecimalPlace(carbonEmission));
            processEmissionVo.setPercent(AnalysisUtil.calculateRate(carbonEmission, totalYearCarbonEmission) + "%");
            processEmissionVoList.add(processEmissionVo);
        }
        processEmissionVoList = processEmissionVoList.stream().sorted((o1, o2) -> o2.getPercent().compareTo(o1.getPercent())).collect(Collectors.toList());
        return ResponseResult.okResult(processEmissionVoList);
    }

    @Override
    public ResponseResult queryEmissionMonth() {
        return carbonTargetService.queryTargetRank();
    }

    @Override
    public Double curYearEmission() {
        Map<String, Double> map = queryTotalStageYearCO2(LocalDate.now().getYear());
        Double d1 = map.get(FUEL_COMBUSTION);
        Double d2 = map.get(INDUSTRY_PRODUCE);
        Double d3 = map.get(CARBON_SEQUESTRATION_PRODUCT);
        Double d4 = map.get(ELECTRIC_HEAT);
        return d1 + d2 + d3 + d4;
    }

    @Override
    public ResponseResult query12MonthEmission() {
        int year = LocalDate.now().getYear();
        Map<String, Object> map1 = listYearVaryMaterialOneTo12CO2(year, 1);
        Map<String, Object> map2 = listYearVaryMaterialOneTo12CO2(year, 2);
        Map<String, Object> map3 = listYearVaryMaterialOneTo12CO2(year, 3);
        Map<String, Object> map4 = listYearVaryMaterialOneTo12CO2(year, 4);
        List<List<Year1To12MonthMaterialVo>> o1 = (List<List<Year1To12MonthMaterialVo>>) map1.get("list");
        List<List<Year1To12MonthMaterialVo>> o2 = (List<List<Year1To12MonthMaterialVo>>) map2.get("list");
        List<List<Year1To12MonthMaterialVo>> o3 = (List<List<Year1To12MonthMaterialVo>>) map3.get("list");
        List<List<Year1To12MonthMaterialVo>> o4 = (List<List<Year1To12MonthMaterialVo>>) map4.get("list");
        List<MonthVo> monthVos = new ArrayList<>(12);
        for (int i = 0; i < 12; i++) {
            monthVos.add(new MonthVo(String.valueOf(i + 1), 0.0));
        }
        for (List<Year1To12MonthMaterialVo> voList : o1) {
            for (int i = 0; i < voList.size(); i++) {
                MonthVo monthVo = monthVos.get(i);
                monthVo = monthVo == null ? new MonthVo() : monthVo;
                monthVo.setEmission(monthVo.getEmission() + voList.get(i).getCarbonEmission());
                monthVo.setDate(String.valueOf(voList.get(i).getMonth()));
            }
        }
        for (List<Year1To12MonthMaterialVo> voList : o2) {
            for (int i = 0; i < voList.size(); i++) {
                MonthVo monthVo = monthVos.get(i);
                monthVo = monthVo == null ? new MonthVo() : monthVo;
                monthVo.setEmission(monthVo.getEmission() + voList.get(i).getCarbonEmission());
                monthVo.setDate(String.valueOf(voList.get(i).getMonth()));
            }
        }
        for (List<Year1To12MonthMaterialVo> voList : o3) {
            for (int i = 0; i < voList.size(); i++) {
                MonthVo monthVo = monthVos.get(i);
                monthVo = monthVo == null ? new MonthVo() : monthVo;
                monthVo.setEmission(monthVo.getEmission() + voList.get(i).getCarbonEmission());
                monthVo.setDate(String.valueOf(voList.get(i).getMonth()));
            }
        }
        for (List<Year1To12MonthMaterialVo> voList : o4) {
            for (int i = 0; i < voList.size(); i++) {
                MonthVo monthVo = monthVos.get(i);
                monthVo = monthVo == null ? new MonthVo() : monthVo;
                monthVo.setEmission(monthVo.getEmission() + voList.get(i).getCarbonEmission());
                monthVo.setDate(String.valueOf(voList.get(i).getMonth()));
            }
        }
        return ResponseResult.okResult(monthVos);
    }

    @Override
    public Map<String, Double> queryTotalStageCO2() {
        Map<String, Double> map = new HashMap<>();

        List<FossilFuel> fossilFuelList = fossilFuelMapper.selectList(null);
        double fossilFuel = fossilFuelList.stream()
                .mapToDouble(FossilFuel::getCarbonEmission)
                .sum();
        map.put(FUEL_COMBUSTION, fossilFuel);

        List<IndustoryProduce> industoryProduceList = industoryProduceMapper.selectList(null);
        double industryProduce = industoryProduceList.stream()
                .mapToDouble(IndustoryProduce::getCarbonEmission)
                .sum();
        map.put(INDUSTRY_PRODUCE, industryProduce);

        List<ElectricHeat> electricHeatList = electricHeatMapper.selectList(null);
        double electricHeat = electricHeatList.stream()
                .mapToDouble(ElectricHeat::getCarbonEmission)
                .sum();
        map.put(ELECTRIC_HEAT, electricHeat);

        List<FixCarbon> fixCarbonList = fixCarbonMapper.selectList(null);
        double fixCarbon = fixCarbonList.stream()
                .mapToDouble(FixCarbon::getCarbonEmission)
                .sum();
        map.put(CARBON_SEQUESTRATION_PRODUCT, fixCarbon);

        return map;
    }

    @Override
    public ResponseResult getProportionStage() {
        Map<String, Double> map = queryTotalStageCO2();
        Double fossiFuel = map.get(FUEL_COMBUSTION);
        Double industryProduce = map.get(INDUSTRY_PRODUCE);
        Double electricHeat = map.get(ELECTRIC_HEAT);
        Double fixCarbon = map.get(CARBON_SEQUESTRATION_PRODUCT);

        Double total = fixCarbon + fossiFuel + industryProduce + electricHeat;

        List<PercentVo> percentVos = new ArrayList<>();

        // 燃料燃烧占比
        double v1 = getCarbonPercent(fossiFuel, total);
        percentVos.add(new PercentVo(v1));
        // 工业生产占比
        double v2 = getCarbonPercent(industryProduce, total);
        percentVos.add(new PercentVo(v2));
        // 电力热力占比
        double v3 = getCarbonPercent(electricHeat, total);
        percentVos.add(new PercentVo(v3));
        // 固碳产品占比
        double v4 = getCarbonPercent(fixCarbon, total);
        percentVos.add(new PercentVo(v4));
        return ResponseResult.okResult(percentVos);
    }

    private double getCarbonPercent(Double count, Double total) {
        BigDecimal molecule = BigDecimal.valueOf(count);
        BigDecimal denominator = BigDecimal.valueOf(total);
        if (denominator.doubleValue() == 0) {
            return 0;
        }
        return molecule.divide(denominator, 2, RoundingMode.UP).doubleValue();
    }

    @Override
    public Double queryTotalCO2() {
        Map<String, Double> map = queryTotalStageCO2();
        Double fossiFuel = map.get("燃料燃烧");
        Double industoryProduce = map.get("工业生产");
        Double electricHeat = map.get("电力热力");
        Double fixCarbon = map.get("固碳产品");
        return BigDecimal.valueOf(fixCarbon).add(BigDecimal.valueOf(electricHeat))
                .add(BigDecimal.valueOf(industoryProduce)).add(BigDecimal.valueOf(fossiFuel))
                .setScale(2, RoundingMode.UP).doubleValue();
    }

    @Override
    public List<StageVo> listStage() {
        StageEnum[] stageEnums = StageEnum.values();
        return Stream.of(stageEnums).map(StageVo::new).collect(Collectors.toList());
    }

    @Override
    public ResponseResult queryYearVaryMaterial1To12CO2(Integer year, Integer stage) {

        return null;
    }

    @Override
    public ResponseResult getAllYears() {

        LocalDate now = LocalDate.now();
        int year = now.getYear();
        List<Integer> collect = new ArrayList<>();
        for (int i = year - 11; i <= year; i++) {
            collect.add(i);
        }
        return ResponseResult.okResult(collect);
    }

    private List<Long> getVaryFixCarbonId(List<FixCarbon> fixCarbonList) {
        Set<Long> set = new HashSet<>();
        for (FixCarbon fixCarbon : fixCarbonList) {
            set.add(fixCarbon.getFixCarbonId());
        }
        return new ArrayList<>(set);
    }

    private List<Long> getVaryElectricHeatId(List<ElectricHeat> electricHeatList) {
        Set<Long> set = new HashSet<>();
        for (ElectricHeat electricHeat : electricHeatList) {
            set.add(electricHeat.getMaterialId());
        }
        return new ArrayList<>(set);
    }

    private List<Long> getVaryIndustoryMaterialId(List<IndustoryProduce> industoryProduceList) {
        Set<Long> set = new HashSet<>();
        for (IndustoryProduce industoryProduce : industoryProduceList) {
            set.add(industoryProduce.getMaterialId());
        }
        return new ArrayList<>(set);
    }

    private List<Integer> getVaryFossiId(List<FossilFuel> fossilFuelList) {
        Set<Integer> set = new HashSet<>();
        for (FossilFuel fossilFuel : fossilFuelList) {
            set.add(fossilFuel.getFossiId());
        }
        return new ArrayList<>(set);
    }
}
